package com.copy.proxy.registery;

import com.copy.pojo.EasyCopyFactoryBean;
import com.copy.proxy.create.GenericCreatePorxyHandler;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.stereotype.Component;

import java.util.Iterator;
import java.util.Map;
/**
 * author: liziyun
 * date: 2019-9-30
 * email: root@ofo.email
 * describe: 注册代理对象到Spring的IOC容器
 *
 */
@Component
public class RegistryProxyTpSpringApplicationContext extends GenericCreatePorxyHandler implements  BeanDefinitionRegistryPostProcessor,RegisteryProxyStrategy  {
    private BeanDefinitionRegistry beanDefinitionRegistry;

    public RegistryProxyTpSpringApplicationContext(String basePackage) {
        super(basePackage);
    }
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        this.beanDefinitionRegistry=beanDefinitionRegistry;
        super.refresh();
        Iterator<Map.Entry<Class, Object>> entrys = proxyBeans.entrySet().iterator();
        while (entrys.hasNext()){
            Map.Entry<Class, Object> entry = entrys.next();
            Class key = entry.getKey();
            Object value = entry.getValue();
            registerProxy(value,key);
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        //不处理
    }

    @Override
    public void registerProxy(Object proxyBean, Class cls) {
        //创建Spring的Bean定义信息
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(cls);
        GenericBeanDefinition definition = (GenericBeanDefinition) builder.getRawBeanDefinition();
        // 属性注入definition.getPropertyValues().add("interfaceType", beanClazz);FactoryBean提供setter方法，否则会注入失败
        // FactoryBean构造方法
        definition.getConstructorArgumentValues().addIndexedArgumentValue(0, cls);
        definition.getConstructorArgumentValues().addIndexedArgumentValue(1, proxyBean);
        //注意，这里的Class是生成Bean实例的工厂，不是Bean本身。
        definition.setBeanClass(EasyCopyFactoryBean.class);
        //这里采用的是byType方式注入，类似的还有byName等
        definition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
        beanDefinitionRegistry.registerBeanDefinition(cls.getSimpleName(), definition);
    }
}
